﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Transactions;
using System.Web;
using System.Web.Http;
using FimetContoDeposito.BLL;
using FimetContoDeposito.BLL.Facades;
using FimetContoDeposito.BLL.Metadata;
using FimetContoDeposito.BLL.Objects;
using FimetContoDeposito.BLL.ResultSets;
using FimetContoDeposito.DAL;
using GrayParrot.Core;
using GrayParrot.Core.Json;
using GrayParrot.Web;
using GrayParrot.Web.Controls;
using GrayParrot.Web.Formly;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace FimetContoDeposito.Controllers
{
    public class MovimentiClienteController : ApiController
    {
        private CustomerOperatorBag GetCurrentCustomer()
        {
            CustomerOperatorBag retValue = null;

            string m_name = HttpContext.Current.User.Identity.Name;
 
            Guid m_id = Guid.Empty;
            using (CustomerOperatorsFacade m_cof = CustomerOperatorsFacade.Create())
            {
                ReturnValue<CustomerOperatorBag> m_operator = m_cof.GetCustomerOperatorBags(m_name);

                if (m_operator.HasValue && m_operator.Value != null)
                {
                    retValue = m_operator.Value;
                }
            }

            return retValue;
        }

        [HttpGet]
        public string LoadFieldsMovimentoCarico()
        {
            string retValue = null;

            CustomerOperatorBag m_currentUser = GetCurrentCustomer();

            if (m_currentUser != null)
            {
                var m_fields = FormlyHelper.ToFormly<AnagraficaDocumentiMetadataCarico>(typeof(AnagraficaDocumentiMetadataCarico));

                m_fields.DefaultValue<string>("Customer", m_currentUser.Customer.Value.ToString());
                m_fields.Disable("Customer");

                retValue = FormlyHelper.Serialize(m_fields);
            }

            return retValue;
        }

        [HttpGet]
        public string[] LoadFieldsMovimentoCarico(Guid id)
        {
            string[] retValue = new string[2] { string.Empty, string.Empty };

            AnagraficaDocumentiMetadataCarico obj = null;

            using (MovimentiFacade m_cof = MovimentiFacade.Create())
            {
                ReturnValue<FCD_Movimenti> m_res = m_cof.Get(id, "FCD_AnagraficaDocumenti");

                if (m_res.HasValue && m_res.Value != null)
                {
                    obj = new AnagraficaDocumentiMetadataCarico();
                    obj.Customer = m_res.Value.Customer;
                    obj.DataMovimento = m_res.Value.DataMovimento.Value;

                    if (m_res.Value.FCD_AnagraficaDocumenti != null)
                    {
                        obj.DataDocumento = m_res.Value.FCD_AnagraficaDocumenti.DataDocumento;
                        obj.NumeroDocumento = m_res.Value.FCD_AnagraficaDocumenti.NumeroDocumento;
                        obj.TipoDocumento = m_res.Value.FCD_AnagraficaDocumenti.TipoDocumento;
                    }
                }
            }

            var m_fields = FormlyHelper.ToFormly<AnagraficaDocumentiMetadataCarico>(typeof(AnagraficaDocumentiMetadataCarico));

            retValue[0] = FormlyHelper.Serialize(m_fields);

            retValue[1] = JsonConvert.SerializeObject(obj);

            return retValue;
        }

        [HttpGet]
        public string LoadFieldsMovimentoScarico()
        {
            string retValue = null;

            string m_name = HttpContext.Current.User.Identity.Name;
            Console.Write(m_name);

            Guid m_id = Guid.Empty;
            using (CustomerOperatorsFacade m_cof = CustomerOperatorsFacade.Create())
            {
                ReturnValue<CustomerOperatorBag> m_operator = m_cof.GetCustomerOperatorBags(m_name);

                if (m_operator.HasValue && m_operator.Value != null)
                {
                    if (m_operator.Value.Customer.HasValue)
                    {
                        m_id = m_operator.Value.Customer.Value;
                    }
                }
            }

            if (m_id != Guid.Empty)
            {
                var m_fields = FormlyHelper.ToFormly<AnagraficaDocumentiMetadataScarico>(typeof(AnagraficaDocumentiMetadataScarico));

                m_fields.DefaultValue<string>("Customer", m_id.ToString());
                m_fields.Disable("Customer");
                m_fields.Hide("TotGiacenza");
                m_fields.Hide("Impegnata");

                retValue = FormlyHelper.Serialize(m_fields);
            }

            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage SalvaDatiDocumentoCarico(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;

            Guid m_idFornitore = Guid.Parse(json.data.Fornitore.ToString());
            Guid m_idCustomer = Guid.Parse(json.data.Customer.ToString());
            Guid m_idTipoDoc = Guid.Parse(json.data.TipoDocumento.ToString());

            string m_note = json.data.Note.ToString();

            DateTime m_dataDocumento = DateTime.Parse(json.data.DataDocumento.ToString());

            DateTime m_dataMovimento = DateTime.Now;
            string m_dataMovimentoS = json.data.DataMovimento.ToString();
            if (!string.IsNullOrWhiteSpace(m_dataMovimentoS))
            {
                m_dataMovimento = DateTime.Parse(m_dataMovimentoS);
            }

            using (TransactionScope scope = new TransactionScope())
            {
                FCD_AnagraficaDocumenti m_anagDdt = new FCD_AnagraficaDocumenti();
                m_anagDdt.Id = Guid.NewGuid();
                m_anagDdt.NumeroDocumento = json.data.NumeroDocumento;
                m_anagDdt.DataDocumento = m_dataDocumento;
                m_anagDdt.Customer = m_idCustomer;
                m_anagDdt.TipoDocumento = m_idTipoDoc;

                ReturnValue<bool> m_resultDDT = null;
                using (AnagraficaDocumentiFacade m_addt = AnagraficaDocumentiFacade.Create())
                {
                    m_resultDDT = m_addt.Add(m_anagDdt);

                    if (m_resultDDT.HasValue)
                    {
                        if (m_resultDDT.Value)
                        {
                            using (MovimentiFacade m_dc = MovimentiFacade.Create())
                            {
                                // creo il movimento di carico...
                                FCD_Movimenti m_mov = new FCD_Movimenti();
                                m_mov.Id = Guid.NewGuid();
                                m_mov.IdDdt = m_anagDdt.Id;
                                m_mov.NumeroDocumento = json.data.NumeroDocumento;
                                m_mov.DataRegistrazione = DateTime.Now;
                                m_mov.DataMovimento = m_dataMovimento;
                                m_mov.TipoOperazione = (short)TipoOperazione.Deposito;
                                m_mov.TipoMovimento = (short)TipoMovimento.OrdineCarico;
                                m_mov.Customer = m_idCustomer;
                                m_mov.Note = m_note;
                                m_mov.RegistratoDaUtente = true;
                                m_mov.DataRegistrazioneUtente = DateTime.Now;

                                ReturnValue<bool> result = m_dc.Add(m_mov);

                                if (result.HasValue)
                                {
                                    if (result.Value)
                                    {
                                        ObjectIdentifierBag bag = new ObjectIdentifierBag(m_mov.Id);
                                        string msg = JsonConvert.SerializeObject(bag);
                                        retValue = Request.CreateResponse(HttpStatusCode.OK, msg);
                                    }
                                }
                                else
                                {
                                    if (result.HasError)
                                    {
                                        retValue = Request.CreateResponseMessage(result.Error.Message, ResponseMessageTypes.Info);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (m_resultDDT.HasError)
                        {
                            retValue = Request.CreateResponseMessage(m_resultDDT.Error.Message, ResponseMessageTypes.Info);
                        }
                    }

                    scope.Complete();
                }
            }

            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage SalvaElementoScarico(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;

            using (TransactionScope scope = new TransactionScope())
            {
                using (MovimentoDettaglioFacade m_mdf = MovimentoDettaglioFacade.Create())
                {
                    Guid m_idArticolo = Guid.Parse(json.data.Articolo.ToString());
                    decimal m_quantita = json.data.Quantita;

                    FCD_MovimentiDettaglio m_movD = new FCD_MovimentiDettaglio();
                    m_movD.Articolo = m_idArticolo;
                    m_movD.Id = Guid.NewGuid();
                    m_movD.IdMovimento = json.idMovimento;
                    m_movD.Quantita = m_quantita;
                    m_movD.CodiceColore = json.data.Colore;
                    m_movD.Priorita = (json.data.Priorita == null ? false : true);

                    ReturnValue<bool> resultD = m_mdf.Add(m_movD);

                    if (resultD.HasValue)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Ordine Prelievo Inserito");
                    }
                    else
                    {
                        if (resultD.HasError)
                        {
                            retValue = Request.CreateResponseMessage(resultD.Error.Message, ResponseMessageTypes.Error);
                        }
                    }
                }

                scope.Complete();
            }

            return retValue;
        }

        /// <summary>
        /// Carica i movimenti del cliente loggato ancora non evasi
        /// </summary>
        /// <param name="data">The data.</param>
        /// <remarks>Quando il movimento viene accettato dall'operatore e diventa quindi evaso, non è piu possibile modificarlo</remarks>
        /// <returns></returns>
        [HttpPost]
        public System.Net.Http.HttpResponseMessage LoadMovimentiClienteNonEvasi(DTParameters data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            CustomerOperatorBag m_currentUser = GetCurrentCustomer();

            using (MovimentiFacade m_dc = MovimentiFacade.Create())
            {
                ReturnValue<IQueryable<Cronologia>> m_objs = m_dc.GetMovimentiNonAccettatiBags(m_currentUser.Customer.Value);

                DTResult<Cronologia> result = DTResult<Cronologia>.Empty("Nessun elemento trovato");
                if (m_objs.HasValue)
                {
                    MovimentiResultSet m_rs = new MovimentiResultSet(data, m_objs.Value);
                    result = m_rs.GetResult();
                }
                else
                {
                    if (m_objs.HasError)
                    {
                        result.Message.MessageType = MessageTypes.Error;
                        result.Message.Message = m_objs.Error.Message;
                    }
                }

                retValue = Request.CreateResponse(HttpStatusCode.OK, result);
            }

            return retValue;
        }

        /// <summary>
        /// Carica il dettaglio di un ordine di carico non evaso...
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        [HttpPost]
        public System.Net.Http.HttpResponseMessage LoadMovimentiClienteNonEvasiDetails(DettaglioCronologiaParams data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            CustomerOperatorBag m_currentUser = GetCurrentCustomer();

            using (MovimentiFacade m_mf = MovimentiFacade.Create())
            {
                List<FCD_GetDettaglioMovimentoCaricoClienteReturnModel> m_dettaglio = m_mf.GetDettaglioMovimentoCaricoClienteEdit(data.IDMovimento);

                DTResult<FCD_GetDettaglioMovimentoCaricoClienteReturnModel> result = DTResult<FCD_GetDettaglioMovimentoCaricoClienteReturnModel>.Empty("Nessun elemento trovato");

                if ((m_dettaglio != null) && (m_dettaglio.Count() > 0))
                {
                    GetDettaglioMovimentoCaricoClienteResultSet m_rs = new GetDettaglioMovimentoCaricoClienteResultSet(data, m_dettaglio.AsQueryable());
                    result = m_rs.GetResult();
                }

                retValue = Request.CreateResponse(HttpStatusCode.OK, result);
            }

            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage CancellaOrdiniNonEvasi()
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            CustomerOperatorBag m_currentUser = GetCurrentCustomer();

            using (MovimentiFacade m_mf = MovimentiFacade.Create())
            {
                ReturnValue<bool> m_res = m_mf.CancellaOrdiniNonEvasi(m_currentUser.Customer.Value);

                if (m_res.HasValue && m_res.Value)
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, m_res.Message);
                }
                else
                {
                    if (m_res.HasError)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, m_res.Error.Message);
                    }
                    else
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Operazione non eseguita");
                    }
                }
            }
            
            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage CancellaOrdineNonEvaso(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;

            Guid m_idMovimento = Guid.Parse(json.Id.ToString());

            CustomerOperatorBag m_currentUser = GetCurrentCustomer();

            using (MovimentiFacade m_mf = MovimentiFacade.Create())
            {
                ReturnValue<bool> m_res = m_mf.CancellaOrdineNonEvaso(m_currentUser.Customer.Value, m_idMovimento);

                if (m_res.HasValue && m_res.Value)
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, m_res.Message);
                }
                else
                {
                    if (m_res.HasError)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, m_res.Error.Message);
                    }
                    else
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Operazione non eseguita");
                    }
                }
            }

            return retValue;
        }

        [HttpPost]
        public System.Net.Http.HttpResponseMessage CancellaDettaglioOrdineNonEvaso(JObject data)
        {
            System.Net.Http.HttpResponseMessage retValue = new HttpResponseMessage(HttpStatusCode.InternalServerError);

            dynamic json = data;

            Guid m_idMovimentoDettaglio = Guid.Parse(json.Id.ToString());

            using (MovimentiFacade m_mf = MovimentiFacade.Create())
            {
                ReturnValue<bool> m_res = m_mf.CancellaDettaglioOrdineNonEvaso(m_idMovimentoDettaglio);

                if (m_res.HasValue && m_res.Value)
                {
                    retValue = Request.CreateResponse(HttpStatusCode.OK, m_res.Message);
                }
                else
                {
                    if (m_res.HasError)
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, m_res.Error.Message);
                    }
                    else
                    {
                        retValue = Request.CreateResponse(HttpStatusCode.OK, "Operazione non eseguita");
                    }
                }
            }

            return retValue;
        }
    }
}